package com.syh.jn.scm.service.impl.supplier.stock;

import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.domain.DomainEvent;
import com.syh.core.ddd.event.DomainEventBus;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.jn.scm.domain.operation.entity.supplier.OperaSupplier;
import com.syh.jn.scm.domain.operation.event.supplier.OperaSupplierEvent;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherOutBill;
import com.syh.jn.scm.domain.supplier.event.StockOtherOutBillEvent;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherOutBillReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherOutBillRepository;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillMto;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillSto;
import com.syh.jn.scm.dto.supplier.stock.StockOtherOutBillVo;
import com.syh.jn.scm.infrastructure.eventBus.reflex.ReflexEventBus;
import com.syh.jn.scm.service.api.supplier.stock.StockOtherOutBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 其他出库单管理
 */
@Service
@Transactional
public class StockOtherOutBillServiceImpl implements StockOtherOutBillService {

  @Autowired
  private StockOtherOutBillRepository stockOtherOutBillRepositoryImpl;
  @Resource(name = "stockOtherOutReadRepositoryMbImpl")
  private StockOtherOutBillReadRepository stockOtherOutBillReadRepositoryMbImpl;


  @Override
  public Long save(StockOtherOutBillSto stockOtherOutBillSto) {
    StockOtherOutBill stockOtherOutBill = new StockOtherOutBill(stockOtherOutBillSto);
    return stockOtherOutBillRepositoryImpl.add(stockOtherOutBill);
  }


  @Override
  public void update(StockOtherOutBillMto stockOtherOutBillMto) {
    StockOtherOutBill stockOtherOutBill = this.stockOtherOutBillRepositoryImpl.getById(stockOtherOutBillMto.getId(), false);
    stockOtherOutBill.modify(stockOtherOutBillMto);
    this.stockOtherOutBillRepositoryImpl.update(stockOtherOutBill);
  }

  @Override
  public void delete(Long id) {
    StockOtherOutBill stockOtherOutBill = stockOtherOutBillRepositoryImpl.getById(id, false);
    stockOtherOutBill.destroy();
    stockOtherOutBillRepositoryImpl.removeById(id);
  }

  @Override
  public StockOtherOutBillVo getById(Long id) {
    StockOtherOutBillVo stockOtherOutBillVo = this.stockOtherOutBillReadRepositoryMbImpl.getById(id);
    List<StockOtherOutBillItemVo> stockOtherOutBillItemVos = this.stockOtherOutBillReadRepositoryMbImpl.findStockOtherOutBillItemVoByBillId(id);
    stockOtherOutBillVo.setItems(stockOtherOutBillItemVos);
    return stockOtherOutBillVo;
  }

  @Override
  public void cancel(Long id) {
    StockOtherOutBill stockOtherOutBill = this.stockOtherOutBillRepositoryImpl.getById(id, false);
    stockOtherOutBill.cancel();
    this.stockOtherOutBillRepositoryImpl.update(stockOtherOutBill, false);
  }

  @Override
  public void confirm(Long id, Long recordDateTimestamp) {
    StockOtherOutBill stockOtherOutBill = this.stockOtherOutBillRepositoryImpl.getById(id);
    stockOtherOutBill.confirm(recordDateTimestamp);
    this.stockOtherOutBillRepositoryImpl.update(stockOtherOutBill, false);
    this.publicEvent(StockOtherOutBillEvent.buildStockOtherOutBillConfirmStatus(new Object[]{stockOtherOutBill}));
  }

  @Override
  public void cancelConfirm(Long id) {
    StockOtherOutBill stockOtherOutBill = this.stockOtherOutBillRepositoryImpl.getById(id);
    StockOtherOutBill oldBill = this.stockOtherOutBillRepositoryImpl.getById(id);
    stockOtherOutBill.cancelConfirm();
    this.stockOtherOutBillRepositoryImpl.update(stockOtherOutBill, false);
    this.publicEvent(StockOtherOutBillEvent.buildStockOtherOutBillCancelConfirmStatus(new Object[]{stockOtherOutBill,oldBill}));
  }

  @Override
  public void unLock(Long id) {
    StockOtherOutBill stockOtherOutBill = this.stockOtherOutBillRepositoryImpl.getById(id);
    stockOtherOutBill.unLock();
    this.stockOtherOutBillRepositoryImpl.update(stockOtherOutBill, false);
  }

  @Override
  public boolean contains(Long id) {
    return stockOtherOutBillRepositoryImpl.contains(id);
  }

  @Override
  public List<StockOtherOutBillVo> findList(Wrapper wrapper) {
    return this.stockOtherOutBillReadRepositoryMbImpl.getList(wrapper);
  }

  @Override
  public List<StockOtherOutBillVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.stockOtherOutBillReadRepositoryMbImpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public StockOtherOutBillVo getOne(Wrapper wrapper) {
    return this.stockOtherOutBillReadRepositoryMbImpl.getOne(wrapper);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    return this.stockOtherOutBillReadRepositoryMbImpl.getCount(wrapper);
  }

  @Override
  public List<StockOtherOutBillItemVo> findStockOtherOutBillItemVoListByOutBillId(Long stockOtherOutBillId) {
    return stockOtherOutBillReadRepositoryMbImpl.findStockOtherOutBillItemVoByBillId(stockOtherOutBillId);
  }

  @Override
  public int getStockOtherOutBillItemVoCount(Wrapper wrapper) {
    return stockOtherOutBillReadRepositoryMbImpl.findStockOtherOutBillItemVoCount(wrapper);
  }

  @Override
  public List<StockOtherOutBillItemVo> findStockOtherOutBillItemVoListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.stockOtherOutBillReadRepositoryMbImpl.findStockOtherOutBillItemVoListPage(wrapper, startRow, count);
  }

  /**
   * 消费者：监听服务商反开账（删除所有该服务商的其他出库单）
   */
  @DomainEventHandle(OperaSupplierEvent.SUPPLIER_REVERSAL_ACCOUNT)
  protected void handleSupplierReversalAccount(OperaSupplier supplier) {
    this.stockOtherOutBillRepositoryImpl.deleteByBusinessEntityId(supplier.getId());
  }

  /**
   * 发布事件
   *
   * @param event
   */
  //TODO 暂时先写在service内
  public void publicEvent(DomainEvent event) {
    DomainEventBus bus = ReflexEventBus.getEventBus();
    bus.publicEvent(event);
  }

}
